﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StreetlightGames.XnaEngine;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using StreetlightGames.SpaceShooter.Patterns;
using Microsoft.Xna.Framework.Graphics;
using System.Runtime.Serialization;

namespace StreetlightGames.SpaceShooter
{
    public class EnemyShip : ModelObject
    {
        /// <summary>Gets or sets the Speed value</summary>
        public float Speed
        {
            get { return _speed; }
            set { _speed = value; }
        }
        private float _speed = 1000;

        /// <summary>Gets or sets the Target value</summary>
        public Vector3 Target
        {
            get { return _target; }
            set { _target = value; }
        }
        private Vector3 _target;
        
        /// <summary>Gets the Heading value</summary>
        public float Heading
        {
            get
            {
                if (Velocity == Vector3.Zero)
                {
                    return 0;
                }
                return (float)Math.Atan2(-Velocity.Z, Velocity.X) - MathHelper.PiOver2;
            }
        }

        /// <summary>Gets or sets the Pattern value</summary>
        public Patterns.Pattern Pattern
        {
            get { return _pattern; }
            set
            {
                _pattern = value;
                if (_pattern != null)
                {
                    _pattern.Ship = this;
                }
            }
        }
        private Patterns.Pattern _pattern;

        /// <summary>Gets or sets the StartDelay value</summary>
        public double StartDelay
        {
            get { return _startDelay; }
            set { _startDelay = value; }
        }
        private double _startDelay;

        /// <summary>Gets or sets the IsStarted value</summary>
        public bool IsStarted
        {
            get { return _isStarted; }
            set { _isStarted = value; }
        }
        private bool _isStarted;

        /// <summary>Gets the Missiles value</summary>
        public List<Missile> Missiles
        {
            get { return _missiles; }
        }
        private List<Missile> _missiles = new List<Missile>();

        private Explosion _explosion;
        private double _timeSinceLastFire;
        private double _fireDelay;

        public EnemyShip()
        {
            Scale = 10;
            _fireDelay = 0.2;
        }

        public void Initialize(GraphicsDevice graphicsDevice)
        {
            _explosion = new Explosion();
            _explosion.Initialize(graphicsDevice);
        }

        public virtual void LoadContent(ContentManager contentManager)
        {
            if (Missiles.Count == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    Missile missile = new Missile();
                    missile.LoadContent(contentManager);
                    _missiles.Add(missile);
                }
            }
        }

        public override void Update(GameTime gameTime)
        {
            if (IsAlive)
            {
                if (Pattern != null)
                {
                    Pattern.Update(gameTime);
                }
                _timeSinceLastFire += gameTime.ElapsedGameTime.TotalSeconds;
                if (_timeSinceLastFire > _fireDelay)
                {
                    FireMissile();
                }
                Rotation = new Vector3(0, Heading, 0);
                base.Update(gameTime);
            }
            else if (_explosion != null)
            {
                _explosion.Update(gameTime);
            }
            foreach (Missile missile in Missiles)
            {
                missile.Update(gameTime);
            }
        }

        public void Draw(GameTime gameTime, GraphicsDeviceManager graphicsDeviceManager, Camera camera)
        {
            if (_explosion.IsAlive)
            {
                _explosion.Draw(graphicsDeviceManager, camera);
            }
            else if (IsAlive)
            {
                base.Draw(gameTime, camera);
            }
        }

        public virtual void Start()
        {
            IsAlive = true;
            IsStarted = true;
        }

        public void FireMissile()
        {
            if (Pattern is Attack)
            {
                foreach (Missile missile in _missiles)
                {
                    if (!missile.IsAlive)
                    {
                        missile.Position = Position;
                        missile.Launch();
                        missile.Rotation = new Vector3(0, MathHelper.Pi, 0);
                        missile.Velocity = new Vector3(missile.Velocity.X, missile.Velocity.Y, -missile.Velocity.Z);
                        missile.Velocity += new Vector3(Velocity.X, 0, 0);
                        _timeSinceLastFire = 0;
                        _fireDelay = 0.2;
                        return;
                    }
                    _fireDelay = RandomHelper.NextDouble(3, 5);
                }
            }
        }

        internal virtual void Explode()
        {
            IsAlive = false;
            AudioController.Instance.PlayCue("Explosion");
            _explosion.Start(Position, Velocity);
        }

        public void AddPattern(Pattern pattern)
        {
            if (Pattern == null)
            {
                Pattern = pattern;
            }
            else
            {
                Pattern nextPattern = Pattern;
                while (nextPattern.NextPattern != null)
                {
                    nextPattern = nextPattern.NextPattern;
                }
                nextPattern.NextPattern = pattern;
            }
        }

        internal int CalculateScore(PlayerShip playerShip)
        {
            Vector3 relativeVelocity = Velocity - playerShip.Velocity;
            Vector3 delta = Position - playerShip.Position;
            int score = ((int)relativeVelocity.Length() + (int)delta.Length()) / 100 * 10;
            if (score == 0)
            {
                return 1;
            }
            return score;
        }
    }
}
